第八章 异常控制流
8.1 异常
异常(exception)就是控制流中的突变,用来响应处理器状态中的某些变化。
当处理器状态中发生一个重要的变化时,处理器正在执行某个当前指令Icurr
状态被编码为不同的位和信号,而状态变化称为事件(event)。
当处理器检测到有事件发生时,它就会通过一张叫做异常表(exception table)的跳转表,进行一个间接过程调用(异常)
然后执行下面三种操作中的某一个:
- 处理程序将控制返回给当前指令Icurr,即当事件发生时正在执行的指令
- 处理程序将控制返回给Inext,如果没有发生异常将会执行的下一条指令。
- 处理程序终止被中断的程序
8.1.1 异常处理
系统中可能的每种类型的异常都分配了一个唯一的非负整数的异常号(exceptionnum-ber)。
- 处理器的设计者分配的:被零除、缺页、内存访问违例、断点
以及算术运算溢出 - 操作系统内核(操作系统常驻内存的部分)的设计者分配的:系统调用和来自外部I/O设备的信号
异常表
在系统启动时(当计算机重启或者加电时),操作系统分配和初始化一张称为异常表的跳转表,使得表目k包含异常k的处理程序的地址。
运行时处理器检测到发生了一个事件,并且确定了相应的异常号k。随后,处理器触发异常,方法是执行间接过程调用,通过异常表的表目k,转到相应的处理程序。
异常号是到异常表中的索引,异常表的起始地址放在一个叫做异常表基址寄存器(exception table base register)的特殊 CPU寄存器里
异常类似于过程调用,但是有一些重要的不同之处:
- 过程调用时,在跳转到处理程序之前,处理器将返回地址压入栈中。然而,根据异常的类型,返回地址要么是当前指令(当事件发生时正在执行的指令),要么是下一条指令(如果事件不发生,将会在当前指令后执行的指令)。
- 处理器也把一些额外的处理器状态压到栈里,在处理程序返回时,重新开始执行被中断的程序会需要这些状态。
- 如果控制从用户程序转移到内核,所有这些项目都被压到内核栈中,而不是压到用户栈中。
- 异常处理程序运行在内核模式下(见8.2.4节),这意味着它们对所有的系统资源都有完全的访问权限。
8.1.2 异常的类别(重点)
异步异常是由处理器外部的I/O设备中的事件产生的。同步异常是执行一条指令的直接产物
中断
中断是异步发生的,是来自处理器外部的I/O设备的信号的结果。
硬件中断不是何一条专门的指令造成的,因此可以说它是异步的。
硬件中断的异常处理程序称为中断处理程序(interrupt handler)。
当前指令完成执行之后,处理器注意到中断引脚的电压变高了,就从系统总线读取异常号,然后调用适当的中断处理程序。当处理程序返回时,它就将控制返回给下一条指令(也即如果没有发生中断,在控制流中会在当前指令之后的那条指令)。结果是程序继续执行,就好像没有发生过中断一样。
故障指令
陷阱和系统调用
陷阱是有意的异常,是执行一条指令的结果。就像中断处理程序一样,陷阱处理程序将控制返回到下一条指令。陷阱最重要的用途是在用户程序和内核之间提供一个像过程一样的接口,叫做系统调用。
普通的函数运行在用户模式中,用户模式限制了函数可以执行的指令的类型,而且它们只能访问与调用函数相同的栈。
系统调用运行在内核模式中,内核模式允许系统调用执行特权指令,并访问定义在内核中的栈。8.2.4节会更详细地讨论用户模式和内核模式。
故障
故障由错误情况引起,它可能能够被故障处理程序修正。当故障发生时,处理器将控制转移给故障处理程序。如果处理程序能够修正这个错误情况,它就将控制返回到引起故障的指令,从而重新执行它。否则,处理程序返回到内核中的abort例程,abort例程会终止引起故障的应用程序。
终止
终止是不可恢复的致命错误造成的结果,通常是一些硬件错误,比如DRAM或者SRAM位被损坏时发生的奇偶错误。终止处理程序从不将控制返回给应用程序,而是返回给一个abort例程,该例程会终止该应用程序。
- Title: 第八章 异常控制流
- Author: time will tell
- Created at : 2024-12-21 20:35:08
- Updated at : 2024-12-22 12:01:04
- Link: https://sbwrn.github.io/2024/12/21/第八章 异常控制流/
- License: This work is licensed under CC BY-NC-SA 4.0.